﻿/*******************************************************************************
* File Name  : NFSession.h
* Description: 
* Author     : gaoyi_ds
* Time       : 2024-07-30
* Version    : 1.0
* History:
* <author>      <time>      <version >  <desc>
*******************************************************************************/

#pragma once

#include <NFLogicCommon/NFPkgMng.h>

#include "proto_common_role.nanopb.h"
#include "proto_cs_login.nanopb.h"
#include "NFComm/NFObjCommon/NFObject.h"
#include "NFLogicCommon/NFLogicShmTypeDefines.h"
#include "NFComm/NFObjCommon/NFTickByRunIndexOP.h"

class NFPlayer;

enum UnlockMirrorSessionReason
{
    UnlockMirrorSessionReason_Default = 0,      // 默认
    UnlockMirrorSessionReason_Expire,           // 超时
};

enum enuSessionState
{
    SESSION_STATE_NORMAL = 0,   // 正常状态
    SESSION_STATE_TRANSFER = 1,   // 跳服阶段，打包玩家以后，session进入路由状态，此状态这时候给玩家的下行包应该转发给目标session进行下行
    SESSION_STATE_WAIT_ROLE = 2,   // 跳服阶段第一步去目标服创建Session，此session进入此状态，该状态下需cache住玩家的上行请求，直到整个玩家传输过来创建完毕
};

/**
 * @class NFSession
 *
 * 该类继承自NFShmObjTemplate，用于管理逻辑会话。
 * 它提供了特定于逻辑会话的属性和行为，是网络框架中会话管理的一部分。
 *
 * 继承自NFShmObjTemplate，该模板类提供了共享内存对象的基本实现。
 * NFSession类针对EOT_LOGIC_SESSION类型和NFShmObj进行了特定的实现和配置。
 */
class NFSession : public NF_OBJECT_TEMPLATE_MACRO(NFSession, EOT_LOGIC_SESSION, NFObject)
public:
	// 构造函数
	NFSession();

	// 析构函数
	virtual ~NFSession();

	// 初始化创建过程
	int CreateInit();

	// 恢复初始化过程
	int ResumeInit();

public:
	// 连接服务器
	int Connect(NFConnectionInfo* pstConnInfo);
	int Connect(const proto_ff::NFConnectionInfo* pstConnInfo);
	// 断开连接
	int DisConnect(int iType, int iReason);

	// 设置连接信息
	void SetConnInfo(NFConnectionInfo* pstConnInfo)
	{
		m_stConnInfo = *pstConnInfo;
	}

	// 获取连接BUS ID
	int GetConnBusId() const
	{
		return m_stConnInfo.m_iConnBusID;
	}

	// 获取连接索引
	uint64_t GetConnIndex() const
	{
		return m_stConnInfo.m_iConnIdx;
	}

	// 获取OpenID
	std::string GetOpenID() const
	{
		return m_stConnInfo.m_szOpenID.ToString();
	}

	// 获取UIN
	uint64_t GetUIN() const
	{
		return m_stConnInfo.m_ullUin;
	}

	// 设置连接UIN
	void SetConnUin(int64_t uin)
	{
		m_stConnInfo.m_ullUin = uin;
	}

	// 获取登录IP
	std::string GetLoginIP() const
	{
		return m_stConnInfo.m_iLoginIP.ToString();
	}

	// 判断是否为PC端
	bool IsPC() const
	{
		return m_stConnInfo.m_bWorldType == proto_ff::E_PLAT_NONE;
	}

	// 获取平台类型
	char GetPlatformType() const
	{
		return m_stConnInfo.m_chPlatformType;
	}

	// 获取扩展平台类型
	Proto_PlatType GetPlatIDEx()
	{
		return m_stClientInfo.plat_type;
	}

	// 获取平台ID
	int GetPlatID() const
	{
		int platid = 2;

		switch (m_stClientInfo.plat_type)
		{
		case proto_ff::E_PLAT_ANDROID:
			platid = 1;
			break;
		case proto_ff::E_PLAT_IOS:
			platid = 0;
			break;
		default:
			break;
		}

		return platid;
	}

	// 获取世界类型
	int32_t GetWorldType() const
	{
		return m_stConnInfo.m_bWorldType;
	}

	// 获取设备类型
	int32_t GetDeviceType() const;

	// 获取区域ID
	int32_t GetZoneAreaID() const
	{
		return m_iZoneAreaID;
	}

	// 设置区域ID
	void SetZoneAreaID(int iZoneAreaID)
	{
		m_iZoneAreaID = iZoneAreaID;
	}

	// 获取区域ID
	int GetZoneID();

	// 获取连接信息
	const NFConnectionInfo* GetConnInfo()
	{
		return &m_stConnInfo;
	}

	// 获取客户端信息
	const Proto_LoginClientInfo* GetClientInfo()
	{
		return &m_stClientInfo;
	}

	// 获取账号ID
	std::string GetAccountID()
	{
		return m_stConnInfo.m_szOpenID.ToString();
	}

	// 根据登录请求初始化客户端信息
	void InitClientInfoByLoginReq(const proto_ff::Proto_CSLoginReq* pLoginReq);

	// 获取调试信息
	std::string GetDebugInfo() const;

	// 绑定玩家对象
	int BindPlayer(NFPlayer* pPlayer);
	// 获取玩家对象
	NFPlayer* GetPlayer();
	// 获取活跃玩家对象
	NFPlayer* GetActivePlayer();

	// 获取断开连接时间
	uint32_t GetDisConnTime() const
	{
		return m_stConnInfo.m_dwDisConnTime;
	}

	// 设置断开连接时间
	void SetDisconnTime(uint32_t dwDisconnTime)
	{
		m_stConnInfo.m_dwDisConnTime = dwDisconnTime;
	}

	// 获取最后活跃时间
	uint32_t GetLastActiveTime() const
	{
		return m_stConnInfo.m_dwLastActiveTime;
	}

	// 设置最后活跃时间
	void SetLastActiveTime(uint32_t dwTimeStamp)
	{
		m_stConnInfo.m_dwLastActiveTime = dwTimeStamp;
	}

	// 激活并检查
	int ActiveAndCheck(uint16_t wMsgId, uint8_t bSubMsgId, uint32_t activeTime, uint16_t wClientSeq);

	// 登录处理
	int Login(const proto_ff::Proto_CSLoginReq* pLoginReq);
    int Login(const proto_ff::Proto_LoginClientInfo* pClientInfo, int loginPri, int loginZoneId);

	// 获取角色ID
	uint64_t GetRoleId();

	// 获取登录通道
	int GetLoginChannel()
	{
		return m_iLoginChannel;
	}

	// 获取客户端版本标志
	int GetClientVersionFlag()
	{
		return m_bClientVersionFlag;
	}

	// 设置客户端版本标志
	void SetClientVersionFlag(uint8_t bFlag)
	{
		m_bClientVersionFlag = bFlag;
	}

	// 设置延迟停止时间
	void SetDelayStopTime(uint64_t tDelayStopTime)
	{
		m_tDelayStopTime = tDelayStopTime;
	}

	// 获取延迟停止时间
	uint64_t GetDelayStopTime()
	{
		return m_tDelayStopTime;
	}

	// 检查包率
	int CheckPkgRate(int msg_id);

	// 判断是否忙碌
	bool IsBusy() const
	{
		return m_bBusy;
	}

	// 设置忙碌状态
	void SetBusy()
	{
		m_bBusy = true;
	}

	// 清除忙碌状态
	void ClearBusy()
	{
		m_bBusy = false;
	}

	// 增加服务器序列号
	uint16_t IncreaseServerSeq()
	{
		return ++m_wServerSeq;
	}

	// 获取服务器序列号
	uint16_t GetServerSeq() const
	{
		return m_wServerSeq;
	}

	// 存储客户端序列号
	void StoreClientSeq(uint16_t wClientSeq)
	{
		m_wClientSeq = wClientSeq;
	}

	// 获取客户端序列号
	uint16_t GetClientSeq() const
	{
		return m_wClientSeq;
	}

	// 判断是否来自QQ游戏中心
	bool IsFromQQGameCenter();
	// 判断是否来自WX游戏中心
	bool IsFromWXGameCenter();

	// 克隆会话序列号
	int CloneSessionSeq(NFSession* pSession);

	// 预注册前处理
	int OnPreRegist(bool bSet);

	// 获取登录优先级
	int GetLoginPri()
	{
		return m_iLoginPri;
	}

	// 设置登录状态
	void SetLogin(bool bSet)
	{
		m_bIsLogin = bSet;
	}

	// 判断是否已登录
	bool IsLogin()
	{
		return m_bIsLogin;
	}

	// 判断是否为招募状态
	bool IsRecruit()
	{
		return m_bIsRecruit;
	}

	// 设置招募状态
	int SetRecruit(bool bRecruit)
	{
		m_bIsRecruit = bRecruit;
		return 0;
	}

	// 获取邀请OpenID
	std::string GetInviteOpenID()
	{
		return m_szInviteOpenID.ToString();
	}

	// 设置邀请OpenID
	int SetInviteOpenID(const std::string& sOpenID)
	{
		m_szInviteOpenID = sOpenID;
		return 0;
	}

	// 获取被邀请者的SOpenID
	std::string GetInvitedSOpenID()
	{
		return m_szInvitedSOpenID.ToString();
	}

	// 设置被邀请者的SOpenID
	int SetInvitedSOpenID(const std::string& sSOpenID)
	{
		m_szInvitedSOpenID = sSOpenID;
		return 0;
	}

	// 设置OpenID
	int SetOpenId(const std::string& szOpenId)
	{
		m_stConnInfo.m_szOpenID = szOpenId;
		return 0;
	}

	// 设置容忍度
	void SetIndulge(bool bindulge) { m_bindulge = bindulge; }

	// 获取容忍度
	bool GetIndulge() { return m_bindulge; }

	// 设置是否为实名认证
	void SetIsRealName(bool real_name) { m_isRealName = real_name; }

	// 获取是否为实名认证
	bool GetIsRealName() { return m_isRealName; }

	bool IsWillDelete() const { return m_isWillDelete; }

	void SetWillDelete();

private:
	// 检查消息ID、时间戳和客户端序列号是否有效
	int Check(uint16_t wMsgId, struct timeval* pstTimeStamp, uint16_t wClientSeq);

public:
	int SendConndStop();
public:
	bool IsLoginQueue() const { return m_bLoginQueue; }
	void SetLoginQueue(bool bLoginQueue) { m_bLoginQueue = bLoginQueue; }
public:
    int LockLoginMirror(uint64_t roleId);
    int UnlockLoginMirror(int reason);
    bool IsLockedLoginMirror();
    bool IsLockedLoginMirrorExpire();
    uint64_t GetLockedLoginMirrorRoleId() { return m_loginMirrorRoleId; }
public:
    int             SetSessionState(enuSessionState eState, int iTargetSessionId, int iTargetSvrId);
    enuSessionState GetSessionState() { return m_eSessionState; }
    int             GetTargetSessionID() { return m_targetSessionId; }
    int             GetTargetSvrID() { return m_targetSvrId; }
    int             TransferCSMsgRes(uint32_t cmd, const google::protobuf::Message* pstMsgRes);
private:
    int             SetRouteInfo(int iTargetSessionId, int iTargetGameSvrId);
private:
	// 管理包装对象的实例
	NFPkgMng m_stPkgMng;

	// 玩家对象ID
	int m_iPlayerObjID; //bind player id
	// 登录通道ID
	int m_iLoginChannel;
	// 延迟停止时间
	uint64_t m_tDelayStopTime;
	// 是否忙碌
	bool m_bBusy;

	// 玩家指针
	NFPlayer* m_pPlayer; //player
	// 连接信息
	NFConnectionInfo m_stConnInfo; //connect info
	// 客户端信息
	Proto_LoginClientInfo m_stClientInfo; //client info
	// 区域ID
	int m_iZoneAreaID;

	// 客户端版本标记
	uint8_t m_bClientVersionFlag; //client version flag

	// 客户端序列号
	uint16_t m_wClientSeq; //current client seq
	// 服务器序列号
	uint16_t m_wServerSeq; //current server seq

	// 是否预注册
	bool m_bPreRegist;
	// 登录优先级
	int m_iLoginPri;

	// 登录区域ID
	int m_iLoginZoneID;
	// 是否已登录
	bool m_bIsLogin;

	// 是否在招人
	bool m_bIsRecruit;
	// 邀请者的OpenID
	NFShmString<128> m_szInviteOpenID;
	// 被邀请者的OpenID
	NFShmString<128> m_szInvitedSOpenID;

	// 是否已计算Android设备数量
	bool m_bAndriodCounted;
	// 是否已计算iOS设备数量
	bool m_bIOSCounted;

	// 是否沉迷
	bool m_bindulge; //该账号是否沉迷 false 表示没有，true 表示有
	// 是否实名认证
	bool m_isRealName; //是否实名
	bool m_isWillDelete; //即将被删除

	bool  m_bLoginQueue;

    int m_loginMirrorTime;
    int m_loginMirrorRoleId;

    enuSessionState m_eSessionState;
    int m_targetSessionId;
    int m_targetSvrId;
};
